﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using JPW.OnlinePaperSubmissionSystem.Project.Dto;
using Kendo.DynamicLinq;
using System.Data.Entity;
namespace JPW.OnlinePaperSubmissionSystem.Project
{

    // [AbpAuthorize(AppPermissions.Pages_Tenant_Instructions)]
    public class InstructionsAppService : AbpZeroTemplateAppServiceBase, IInstructionsAppService
    {
        private readonly IRepository<Instructions, long> _instructionsRepository;
        private readonly IRepository<InstructionsFiles, long> _instructionsFilesRepository;
        private readonly IRepository<Files, long> _filesRepository;
        public InstructionsAppService(
            IRepository<Instructions, long> instructionsRepository,
            IRepository<InstructionsFiles, long> instructionsFilesRepository, IRepository<Files, long> filesRepository
            )
        {
            _instructionsRepository = instructionsRepository;
            _instructionsFilesRepository = instructionsFilesRepository;
            _filesRepository = filesRepository;
        }

        public DataSourceResult KendoGetInstructionss(DataSourceRequest input)
        {
            var instructionss = _instructionsRepository
               .GetAll()
               .OrderBy(p => p.Id)
               .MapTo<List<InstructionsListDto>>().AsQueryable()
               .ToDataSourceResult(input);

            return instructionss;
        }
        public ListResultOutput<InstructionsListDto> GetInstructionss(GetInstructionsInput input)
        {
            var instructionss = _instructionsRepository
            .GetAll()
            //.WhereIf(
            //    !input.Filter.IsNullOrEmpty(),
            //    p => p.Name.Contains(input.Filter) ||
            //            p.Code.Contains(input.Filter) 
            //||p.Performance==Convert.ToInt32(input.Filter)
            //)
            .OrderBy(p => p.Id)
            .ToList();

            return new ListResultOutput<InstructionsListDto>(instructionss.MapTo<List<InstructionsListDto>>());
        }
        public async Task<ListResultOutput<InstructionsListDto>> GetInstructionssAsync()
        {
            var query = await _instructionsRepository.GetAll().OrderBy(p => p.Id).ToListAsync();

            return new ListResultOutput<InstructionsListDto>(query.MapTo<List<InstructionsListDto>>());

        }

        //  [AbpAuthorize(AppPermissions.Pages_Tenant_Instructions_Delete)]//删除须知表把关系表与文件表数据三表删除--删除文件表只删除须知中间表与文件两表
        public async Task DeleteInstructions(IdInput input)
        {
            await _instructionsRepository.DeleteAsync(input.Id);
            await _instructionsFilesRepository.DeleteAsync(x=>x.InstructionsId == input.Id);           
            var query = from n in _instructionsFilesRepository.GetAll()
                        where n.InstructionsId == input.Id
                        select n.FileId;
            foreach (var i in query)
            {
                await _filesRepository.DeleteAsync(x => x.Id == i);
            }    
        }

        public async Task DeleteFiled(IdInput input)
        {
            await _filesRepository.DeleteAsync(input.Id);
            await _instructionsFilesRepository.DeleteAsync(x=>x.FileId==input.Id);
        }

        public async Task CreateOrUpdateInstructions(CreateOrUpdateInstructionsInput input)
        {
            if (input.Instructions.ID.HasValue)
            {
                await UpdateInstructionsAsync(input);
            }
            else
            {
                await CreateInstructionsAsync(input);
            }
        }
        //  [AbpAuthorize(AppPermissions.Pages_Tenant_Instructions_Create)]
        public async Task CreateInstructionsAsync(CreateOrUpdateInstructionsInput input)
        {
            var instructions = input.Instructions.MapTo<Instructions>();
            long id = await _instructionsRepository.InsertAndGetIdAsync(instructions);

            foreach (var fileId in input.FileIds)
            {
                var bb = _instructionsFilesRepository.Count(x => x.FileId == fileId);
                if (bb < 1)
                {
                    InstructionsFiles info = new InstructionsFiles() { InstructionsId = id, FileId = fileId };
                    await CreateInstructionsFilesAsync(info);
                }
            }

        }
        //  [AbpAuthorize(AppPermissions.Pages_Tenant_Instructions_Update)]
        public async Task UpdateInstructionsAsync(CreateOrUpdateInstructionsInput input)
        {
            var instructions = input.Instructions.MapTo<Instructions>();
            await _instructionsRepository.UpdateAsync(instructions);

            foreach (var fileId in input.FileIds)
            {
                var bb = _instructionsFilesRepository.Count(x => x.FileId == fileId);
                if (bb < 1)
                {
                    InstructionsFiles info = new InstructionsFiles() { InstructionsId = instructions.Id, FileId = fileId };
                    await CreateInstructionsFilesAsync(info);
                }
            }

        }
        //  [AbpAuthorize(AppPermissions.Pages_Tenant_Instructions_Update)]
        public async Task<GetInstructionsForEditOutput> GetInstructionsForEdit(NullableIdInput input)
        {
            Instructions instructions = null;
            if (input.Id.HasValue) //Editing existing role?
            {
                instructions = await _instructionsRepository.FirstOrDefaultAsync(input.Id.Value);
            }
            return new GetInstructionsForEditOutput
            {
                Instructions = instructions.MapTo<InstructionsEditDto>(),
            };
        }
        public ListResultOutput<FilesListDto> getFiles(IdInput input)
        {
            List<Files> files = new List<Files>();
            var query = from n in _instructionsFilesRepository.GetAllList()
                        where n.FileId == input.Id
                        select n;
            foreach (var item in query)
            {
                files.Add(item.File);
            }
            return new ListResultOutput<FilesListDto>(files.MapTo<List<FilesListDto>>()); 
        }

        //public List<Files> getFiles(IdInput input)
        //{
        //    List<Files> files = new List<Files>();
        //    var query = from n in _instructionsFilesRepository.GetAllList()
        //                where n.FileId == input.Id
        //                select n;
        //    foreach (var item in query)
        //    {
        //        files.Add(item.File);
        //    }
        //    return files;
        //}


        public DataSourceResult KendoGetInstructionsById(DataSourceRequest input)
        {
            List<Files> files = new List<Files>();
            long instructionId = Convert.ToInt64(input.Filter.Filters.FirstOrDefault(x => x.Field == "id").Value);//提取自己想要的数据！数据也是根据规则排列所以需要一层层解析
            var query = _instructionsFilesRepository.GetAll();
            var filters = input.Filter.Filters.Where(x => x.Field != "id");
            List<long> ids = new List<long>();
            foreach (var item in filters)
            {
                ids.Add(Convert.ToInt64(item.Value));
            }
            if (instructionId > 0)
            {
                query = query.Where(x => x.InstructionsId == instructionId);
                foreach (var item in query)
                {
                    files.Add(item.File);
                }
            }
            if (ids.Count > 0)//新上传
            {
                var queryFiles = _filesRepository.GetAll().Where(x => ids.Contains(x.Id));
                foreach (var item in queryFiles)
                {
                    files.Add(item);
                }
            }
            return files.MapTo<List<FilesListDto>>().AsQueryable()
               .ToDataSourceResult(input.Take, input.Skip, input.Sort, null);
        }


        #region 中间表
        public async Task CreateInstructionsFilesAsync(InstructionsFiles input)
        {
            await _instructionsFilesRepository.InsertAsync(input);
        }

        public async Task UpdateInstructionsFilesAsync(InstructionsFiles input)
        {
            await _instructionsFilesRepository.UpdateAsync(input);
        }
        #endregion
    }
}

